// 3 闭包方式实现一个类
// 3.1
var Book = (function() {
  // 静态私有变量
  var bookNum = 0;
  // 静态私有方法
  function checkBook(name) {}
  // 返回闭包
  return function(newId, newName, newPrice) {
    // 私有变量
    var name, price;
    // 私有方法
    function checkID(id) {}
    // 特权方法
    this.getName = function() {}
    this.getPrice = function() {}
    this.setName = function() {}
    this.setPrice = function() {}
    // 公有属性
    this.id = newId;
    // 公有方法
    this.copy = function() {}
    bookNum++;
    if (bookNum > 100) {
      throw new Error('我们仅出版100本书.');
    }
    // 构造器
    this.setName(newName);
    this.setPrice(newPrice);
  }
}());
Book.prototype = {
  // 公有属性
  isJSBook: false,
  // 公有方法
  display: function() {}
}

// 3.2 将3.1中暴露再外部的Book.prototype 转移到函数内部
var Book = function() {
  // 静态私有变量
  var bookNum = 0;
  // 静态私有方法
  function checkBook(name) {}
  // 创建类
  function _book(newId, newName, newPrice) {
    // 私有变量
    var name, price;
    // 私有方法
    function checkID() {}
    // 特权方法
    this.getName = function() {}
    this.getPrice = function() {}
    this.setName = function() {}
    this.setPrice = function() {}
    // 公有属性
    this.id = newId;
    // 公有方法
    this.copy = function() {}
    bookNum++;
    if (bookNum > 100) {
      throw new Error('我们仅出版100本书');
    }
    // 构造器
    this.setName(newName);
    this.setPrice(newPrice);
  }
  // 构建原型
  _book.prototype = {
    // 静态公有属性
    isJSBook: false,
    // 静态公有方法
    display: function() {}
  }
  return _book;
}


// 4 定义安全类，防止遗漏new关键字
function Book(title, time, type) {
  // 判断执行过程中this是否时当前这个对象
  if (this instanceof Book) {
    // 如果是则直接构造
    this.title = title;
    this.time = time;
    this.type = type;
  } else {
    // 否则重新创建这个对象
    return new Book(title, time, type);
  }
}
// 使用
var book = Book('JavaScript 设计模式', '2014', 'js');
console.log(book);
console.log(book.title);
console.log(book.time);
console.log(book.type);
try {
  console.log(window.title);
  console.log(window.time);
  console.log(window.type);
} catch(e) {
  console.log(e.message);
}

